package fr.nts.framework.front.security.service.userdetails;

import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;

import fr.nts.framework.database.jpa.enumeration.NTSDroit;
import fr.nts.framework.database.jpa.model.security.SecurityUser;
import fr.nts.framework.front.security.service.SimpleUserService;
import fr.nts.framework.front.security.service.exception.BadLoginException;
import fr.nts.framework.front.security.service.model.SimpleUserDetails;

/**
 * Classe héritant d'une interface Spring Security qui définit les caractéristiques d'un utilisateur NTS.
 * 
 * @author sco
 * @version 1.0.0
 */
@Component("simpleUserDetailsService")
public class SimpleUserDetailsService implements UserDetailsService{

	private static final Logger log = LoggerFactory.getLogger(SimpleUserDetailsService.class);

    @Resource(name = "simpleUserService")
    private SimpleUserService simpleUserService;
    
    
    /*
     * (non-Javadoc)
     * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
     */
    @Override
    public UserDetails loadUserByUsername(final String login) throws UsernameNotFoundException, 
                                                                     DataAccessException{

        // On recherche l'objet émployé avec le service utilisateur correspond au login en paramètre
    	SecurityUser user  = null;
        try{
        	user = simpleUserService.load(login);
        }catch(BadLoginException e){
            log.warn("Le login [{}] qui veux s'authentifier n'a pas été trouvé.", 
                     login);
           throw new UsernameNotFoundException("L'utilisateur qui a pour login [" + login + "] n'existe pas");
		}
        
        List<GrantedAuthority> grantedAuthorities = Lists.newArrayList();
        
        // Utilisateur classique
        // Si l'utilisateur classique a des droits
        if(!user.getDroits().isEmpty()){
        	
            // On créé des rôles spring
            for(NTSDroit droit: user.getDroits()){
            	grantedAuthorities.add(new GrantedAuthorityImpl(droit.name()));
            }
            
        // Aucun droit
        }else{
            log.warn("L'utilisateur [{}] n'a aucun droit !", login);
        }
        
        if(user.getRole() != null){
	        // Le role principale est aussi considéré comme une role security
	        grantedAuthorities.add(new GrantedAuthorityImpl(user.getRole().name()));
        }
        

        // On créé l'objet qui sera utilisé par spring security pour gérer la sécurité
        // L'utilisateur spring security
        SimpleUserDetails employeeDetails = new SimpleUserDetails(login, 
        		                                                  user.isActif(), 
			                                                      grantedAuthorities);
        employeeDetails.setName(user.getNom());
        employeeDetails.setFirstname(user.getPrenom());
        
        return employeeDetails;
    }
}